package com.itfreer.gis.arcgis;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.itfreer.gis.OptionResult;
import com.itfreer.gis.OptionType;
import com.itfreer.gis.graphic.GisGraphic;
import com.itfreer.utils.json.JsonUtils;
/**
 * arcgis导入数据操作
 * @author gj
 *
 */
public class ArcgisOption {
	
	/**
	 * arcgis中的数据字段处理逻辑修改
	 * @param attributes
	 */
	public static void filterAttribute(Map<String, Object> attributes) {
		if(attributes!=null && attributes.size()>0) {
			Set<String> keys=attributes.keySet();
			for(String key:keys) {
				Object val=attributes.get(key);
				if(val!=null) {
					if("<空>".equals(val)) {
						attributes.put(key, null);
					}else if(val instanceof Date) {
						Date temp=(Date)val;
						if(temp==null) {
							attributes.put(key, null);
						}else if(temp.getYear()<0) {
							attributes.put(key, null);
						}
					}
				}
			}
		}
	}
	
	
	/**
	 * 添加要素功能
	 * @param baseUrl feature服务地地址如（http://192.168.1.120:6080/arcgis/rest/services/TEST/FeatureServer）
	 * @param layerId 图层id(如 0)
	 * @param graphic 图形
	 * @throws Exception
	 */
	public OptionResult addFeature(String baseUrl,Integer layerId,GisGraphic graphic){
		OptionResult option=new OptionResult();
		option.setGraphic(graphic);
		option.setOptionType(OptionType.add);
		
		try {
			String realUrl=baseUrl+"/"+layerId+"/"+ArcGisConstants.ADD_FEATURES;

			// 创建HTTP客户端
			CloseableHttpClient httpclient = HttpClientBuilder.create().setDefaultRequestConfig(ArcGisConstants.REQUEST_CONFIG).build();
			// 创建POST请求
			HttpPost httpPost = new HttpPost(realUrl);
			// 查询当前新增的box在ArcGis中是否存在
			
			//TODO 数据新增处理逻辑为不需要逻辑处理
			/*Map<String, Object>oldFeature=null;
			if(graphic.getAttribute()!=null && graphic.getAttribute().containsKey(graphic.getKeyField())
					&& graphic.getAttribute().get(graphic.getKeyField())!=null) {
				
				oldFeature = this.queryFeature(baseUrl, layerId,
						null, graphic.getAttribute().get(graphic.getKeyField()).toString());
			}
			
			if (oldFeature != null && oldFeature.size() > 0) {
				return  this.updateFeature(baseUrl, layerId, graphic);
			}*/
			// 运行到这里说明该box在ArcGis中不存在, 执行新增操作
			
			// 创建新的空间模型
			Map<String, Object> geometry = ArcGisUtils.createNewGeometry(graphic);
			// 创建新的数据模型
			Map<String, Object> attributes = graphic.getAttribute();
			filterAttribute(attributes);
			// 创建新的容器模型
			List<Map<String, Object>> features = ArcGisUtils.createNewFeatures(geometry, attributes);
			// 模型对象转换成json字符串
			String jsonStr = JsonUtils.toJSONString(features);
			// 创建POST请求参数, 必须用NameValuePair
			List<NameValuePair> params = new ArrayList<>();
			// 设置传值参数类型为json
			params.add(new BasicNameValuePair("f", "json"));
			// 将转换好的字符串添加到参数中
			params.add(new BasicNameValuePair(ArcGisConstants.FEATURES, jsonStr));
			// 设置POST请求参数,并将参数格式设置为utf-8
			HttpEntity entity = new UrlEncodedFormEntity(params, ArcGisConstants.DEFAULT_CHARSET);
			httpPost.setEntity(entity);
			// 发送请求
			HttpResponse response = httpclient.execute(httpPost);
			// 处理结果集
			if (response.getStatusLine().getStatusCode() == 200) {
			  // 调用EntityUtils.toString方法最后会自动把inputStream close掉的
			  String str = EntityUtils.toString(response.getEntity());
			  System.out.println("要素添加执行结果：");
			  System.out.println(str);
			  HashMap<String, Object> result=new HashMap<String, Object>();
			  result=JsonUtils.toBean(str, result.getClass());
			  
			 // List<Object> lst=new ArrayList<>();
			  Object temp=result.get("addResults");
			  List<Object> lst=(List<Object>)temp;

			  result=  (HashMap<String, Object>)lst.get(0);
			  String success=result.get("success").toString();
			  if("true".equals(success)) {
				  graphic.getAttribute().put(graphic.getKeyField(), result.get("objectId"));
				  return option;
			  }else {
				   result=(HashMap<String, Object>)result.get("error");
				   option.setStatus(false);
				   option.setMessager(result.get("description"));
			  }
   
			  // 释放资源
			  httpclient.close();
			} else {
				option.setStatus(false);
				option.setMessager("网络请求失败");
			  //throw new RuntimeException("ArcGis添加box失败");
			}
		} catch (Exception e) {
			option.setStatus(false);
			option.setMessager("网络请求失败");
		} 
	    return option;
	}
	
	/**
	 * 要素删除功能
	 * @param baseUrl
	 * @param layerId
	 * @param objectids
	 * @param where
	 * @throws Exception
	 */
	public OptionResult deleteFeature(String baseUrl,Integer layerId,List<Integer> objectids,String where) throws Exception {
		OptionResult option=new OptionResult();
		//option.setGraphic(graphic);
		option.setOptionType(OptionType.delete);
		
		if((where==null || "".equals(where)) && (objectids==null || objectids.size()<1)) return option;

		
	    // 创建HTTP客户端
	    CloseableHttpClient httpclient = HttpClientBuilder.create().setDefaultRequestConfig(ArcGisConstants.REQUEST_CONFIG).build();
	    // 创建POST请求
	    String realUrl=baseUrl+"/"+layerId+"/"+ArcGisConstants.DELETE_FEATURES;
	    HttpPost httpPost = new HttpPost(realUrl);
	    // 创建POST请求参数, 必须用NameValuePair
	    List<NameValuePair> params = new ArrayList<>();
	    // 设置传值参数类型为json
	    params.add(new BasicNameValuePair("f", "json"));
	    // 将拼装好的条件添加到参数中
	    if(where!=null && !"".equals(where)) {
		    params.add(new BasicNameValuePair("where", where));
	    }
	    
	    if(objectids!=null && objectids.size()>0) {
		    params.add(new BasicNameValuePair("objectIds", 
		    		JsonUtils.toJSONString(objectids).replace("[", "").replace("]","")));
	    }
	    // 设置POST请求参数,并将参数格式设置为utf-8
	    HttpEntity entity = new UrlEncodedFormEntity(params, ArcGisConstants.DEFAULT_CHARSET);
	    httpPost.setEntity(entity);
	    // 发送请求
	    HttpResponse response = httpclient.execute(httpPost);
	    if (response.getStatusLine().getStatusCode() == 200) {
		      // 调用EntityUtils.toString方法最后会自动把inputStream close掉的
		      String str=EntityUtils.toString(response.getEntity());
		      System.out.println("要素删除执行结果：");
		      System.out.println(str);
		      HashMap<String, Object> result=new HashMap<String, Object>();
			  result=JsonUtils.toBean(str, result.getClass());
			  
			 // List<Object> lst=new ArrayList<>();
			  
			  //删除只有一条记录时，处理记录方式
			  if(result.get("success")!=null) {
				  String success=result.get("success").toString();
				  if("true".equals(success) || "1".equals(success)) {
					  option.setMessager(result.get("objectId"));
					  return option;
				  }
			  }
			  
			  Object temp=result.get("deleteResults");
			  List<Object> lst=(List<Object>)temp;
			  result=  (HashMap<String, Object>)lst.get(0);
			  String success=result.get("success").toString();
			  if("true".equals(success)) {
				 // graphic.getAttribute().put(graphic.getKeyField(), result.get("objectId"));
				  option.setMessager(result.get("objectId"));
				  return option;
			  }else {
				  result=(HashMap<String, Object>)result.get("error");
				  option.setStatus(false);
				  option.setMessager(result.get("description"));
			  }
		      httpclient.close();
	    } else {
	    	 //throw new RuntimeException("ArcGis删除box失败");
	    	 option.setStatus(false);
	    	 option.setMessager("ArcGis删除box失败");
	    }
	    return option;
	}
	
	/**
	 * arcgis要素查询服务
	 * @param baseUrl http://192.168.1.120:6080/arcgis/rest/services/TEST/FeatureServer
	 * @param layerId 0
	 * @param where sheng=44
	 * @param objectIds 8808,8805
	 * @return
	 * @throws Exception
	 */
	public Map<String, Object> queryFeature(String baseUrl,Integer layerId,String where,String objectIds) throws Exception {
	    // 创建HTTP客户端
	    CloseableHttpClient httpclient = HttpClientBuilder.create().setDefaultRequestConfig(ArcGisConstants.REQUEST_CONFIG).build();
	    // 创建POST请求
	    String realUrl=baseUrl+"/"+layerId+"/"+ArcGisConstants.QUERY_FEATURES;
	    HttpPost httpPost = new HttpPost(realUrl);
	    // 创建POST请求参数, 必须用NameValuePair
	    List<NameValuePair> params = new ArrayList<>();
	    // 设置传值参数类型为json
	    params.add(new BasicNameValuePair("f", "json"));
	    // 将拼装好的条件添加到参数中
	    params.add(new BasicNameValuePair("where", where));
	    // 返回所有字段
	    params.add(new BasicNameValuePair("outFields", "*"));
	    if(objectIds!=null && !"".equals(objectIds)) {
	    	  params.add(new BasicNameValuePair("objectIds", objectIds));
	    }
	    //设置http Post请求参数
	    HttpEntity entity = new UrlEncodedFormEntity(params, ArcGisConstants.DEFAULT_CHARSET);
	    httpPost.setEntity(entity);
	    // 发送请求
	    HttpResponse response = httpclient.execute(httpPost);
	    // 处理结果集
	    Map<String, Object> oldFeature = new HashMap<>();
	    if (response.getStatusLine().getStatusCode() == 200) {
	       // 调用EntityUtils.toString方法最后会自动把inputStream close掉的
	       String result = EntityUtils.toString(response.getEntity());
	       //LOGGER.info("arcgis查询box: box = " + result);
	       // 将旧的对象从result解析出来,得到objectid
	       Map<String, Object> data = new HashMap<>();
	       data = JsonUtils.toBean(result, data.getClass());
	       // 得到旧的features集合
	       List<Map<String, Object>> oldFeatures = (List<Map<String, Object>>) data.get(ArcGisConstants.FEATURES);
	       // 获取第一个数据
	       if (oldFeatures.size() > 0) {
	          oldFeature = oldFeatures.get(0);
	       }
	    }
	    // 释放资源
	    httpclient.close();
	    return oldFeature;
	}
	
	/**
	 * 更新要素服务
	 * @param baseUrl
	 * @param layerId
	 * @param graphic
	 * @return
	 */
	public OptionResult updateFeature(String baseUrl,Integer layerId,GisGraphic graphic){
		OptionResult option=new OptionResult();
		option.setGraphic(graphic);
		option.setOptionType(OptionType.update);
		try {
			String realUrl=baseUrl+"/"+layerId+"/"+ArcGisConstants.UPDATE_FEATURES;
			// 创建HTTP客户端
			CloseableHttpClient httpclient = HttpClientBuilder.create().setDefaultRequestConfig(ArcGisConstants.REQUEST_CONFIG).build();
			// 创建post请求
			HttpPost httpPost = new HttpPost(realUrl);
			// 查询当前被修改的box在ArcGis中是否存在
	/*		Map<String, Object> oldFeature = this.queryFeature(baseUrl,layerId,null,graphic.getAttribute().get(graphic.getKeyField()).toString());
			if (oldFeature != null && oldFeature.size() > 0) {
			  // 得到feature里面的attributes
			  Map<String, Object> oldAttributes = (Map<String, Object>) oldFeature.get(ArcGisConstants.ATTRIBUTES);
			  // 得到attributes里面的objectid
			  Integer objectid = (Integer) oldAttributes.get(graphic.getKeyField());
			  
			  if (objectid != null && objectid != 0) {*/
			    // 创建新的数据模型
			    Map<String, Object> geometry = ArcGisUtils.createNewGeometry(graphic);
			    // 创建新的容器模型
			    Map<String, Object> attributes=graphic.getAttribute();
			    filterAttribute(attributes);
			    List<Map<String, Object>> features = ArcGisUtils.createNewFeatures(geometry, attributes);
			    // 将模型对象转换成json字符串
			    String jsonStr = JsonUtils.toJSONString(features);
			    // 创建POST请求参数, 必须用NameValuePair
			    List<NameValuePair> params = new ArrayList<>();
			    // 设置传值参数类型为json
			    params.add(new BasicNameValuePair("f", "json"));
			    // 将转换好的字符串添加到参数中
			    params.add(new BasicNameValuePair(ArcGisConstants.FEATURES, jsonStr));
			    // 设置POST请求参数,并将参数格式设置为utf-8
			    HttpEntity entity = new UrlEncodedFormEntity(params, ArcGisConstants.DEFAULT_CHARSET);
			    httpPost.setEntity(entity);
			    // 发送请求
			    HttpResponse response = httpclient.execute(httpPost);
			    // 处理结果集
			    if (response.getStatusLine().getStatusCode() == 200) {
			          // 调用EntityUtils.toString方法最后会自动把inputStream close掉的
			          String str=EntityUtils.toString(response.getEntity());
			          System.out.print("数据更新执行结果：");
			          System.out.print(str);
			          
			          HashMap<String, Object> result=new HashMap<String, Object>();
					  result=JsonUtils.toBean(str, result.getClass());
					  
					 // List<Object> lst=new ArrayList<>();
					  Object temp=result.get("updateResults");
					  List<Object> lst=(List<Object>)temp;

					  result=  (HashMap<String, Object>)lst.get(0);
					  String success=result.get("success").toString();
					  if("true".equals(success)) {
						 // graphic.getAttribute().put(graphic.getKeyField(), result.get("objectId"));
						  option.setMessager(result.get("objectId"));
						  return option;
					  }else {
						  result=(HashMap<String, Object>)result.get("error");
						  option.setStatus(false);
						  option.setMessager(result.get("description"));
					  }
			          
			          // 释放资源
			          httpclient.close();
			        } else {
			        	option.setStatus(false);
			        	option.setMessager("请求未得到响应");
			        }
			   /* } else {
			    	return this.addFeature(baseUrl, layerId, graphic);
			    }
			} else {
				return this.addFeature(baseUrl, layerId, graphic);
			}*/
			return option;
		} catch (Exception e) {
			return option;
		}
	} 
}
